<?php

namespace App\Services\Third;

use App\Exceptions\ExceptionSms;
use Easemob\Auth;
use Easemob\Block;
use Easemob\Contact;
use Easemob\Group;
use Easemob\Message;
use Easemob\Push;
use Easemob\Room;
use Easemob\User;
use Easemob\UserMetadata;

class EasemobZim
{
    public $app_key;
    public $client_id;
    public $client_secret;
    public $auth;

    /**
     * EasemobZim constructor.
     * @param $app_key
     * @param $client_id
     * @param $client_secret
     * @throws \Exception
     */
    public function __construct($app_key, $client_id, $client_secret)
    {
        $this->app_key       = $app_key;
        $this->client_id     = $client_id;
        $this->client_secret = $client_secret;

        $this->auth = new Auth($this->app_key, $this->client_id, $client_secret);
    }

    /**
     * 是否为聊天室
     * @param $type
     * @return bool
     * @name:isRoom
     * @author: lisa
     * @datetime: 2023-05-19 10:25
     */
    public function isRoom($type): bool
    {
        return $type == 'room';
    }

    /**
     * 是否为群组
     * @param $type
     * @return bool
     * @name:isGroup
     * @author: lisa
     * @datetime: 2023-05-19 10:25
     */
    public function isGroup($type): bool
    {
        return $type == 'group';
    }

    /**
     * 批量注册：单次请求最多可注册 60 个用户 ID。
     * @param array $data 用户数据，结构为：
     * [{
     * "username": "用户 ID，长度不可超过 64 个字节。不可设置为空。",
     * "password": "用户的登录密码，长度不可超过 64 个字符",
     * "nickname": "推送消息时，在消息推送通知栏内显示的用户昵称，并非用户个人信息的昵称。长度不可超过 100 个字符。"
     * }]
     * @return array 结构为：
     * [[
     * "uuid"      => "4d4421f0-f482-11ed-91a4-19ccf324b270",
     * "type"      => "user",
     * "created"   => 1684307599764,
     * "modified"  => 1684307599764,
     * "username"  => "A8894",
     * "activated" => true,
     * "nickname"  => "芦泓钢2",
     * ]]
     * @throws \Exception
     * @author: lisa
     * @datetime: 2023-05-17 14:37
     */
    public function registers($data = [])
    {
        if (count($data) == 0) $this->throwMsg('注册用户信息不能为空');

        if (count($data) > 60) $this->throwMsg("每次最多可注册60个用户");

        foreach ($data as $value) {
            if (empty($value['username'])) $this->throwMsg("用户ID不能为空");
            if (empty($value['password'])) $this->throwMsg("用户密码不能为空");
            if (empty($value['nickname'])) $this->throwMsg("用户昵称不能为空");
        }

        $user   = new User($this->auth);
        $result = $user->create($data);
        \Log::info("环信 - 注册用户响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 更新用户信息
     * @param string $username 用户ID
     * @param array $data
     * [
     * "nickname": "昵称：长度在 64 个字符内"
     * "avatarurl": "头像：长度在 256 个字符内"
     * "phone": "手机号：长度在 32 个字符内"
     * "mail": "邮箱：长度在 64 个字符内"
     * "gender": "性别：0未知 1男 2女"
     * "sign": "签名：长度在 256 个字符内"
     * "birth": "生日：长度在 64 个字符内"
     * ]
     * @return array|bool
     * @name:updateUser
     * @author: lisa
     * @datetime: 2023-05-18 9:04
     */
    public function updateUser($username, $data)
    {
        $user   = new UserMetadata($this->auth);
        $result = $user->setMetadataToUser($username, $data);
        \Log::info("环信 - 更新用户响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    public function getUserInfo($username)
    {
        $user = new UserMetadata($this->auth);
        $result = $user->getMetadataFromUser($username);
        \Log::info("环信 - 获取用户响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 添加好友
     * @param $owner_username
     * @param $friend_username
     * @return array|bool
     * @name:addFriend
     * @author: lisa
     * @datetime: 2023-05-17 15:41
     */
    public function addFriend($owner_username, $friend_username)
    {
        $contact = new Contact($this->auth);
        $result  = $contact->add($owner_username, $friend_username);
        \Log::info("环信 - 添加好友响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 删除好友
     * @param $owner_username
     * @param $friend_username
     * @return array|bool
     * @name:deleteFriend
     * @author: lisa
     * @datetime: 2023-05-17 15:42
     */
    public function deleteFriend($owner_username, $friend_username)
    {
        $contact = new Contact($this->auth);
        $result  = $contact->remove($owner_username, $friend_username);
        \Log::info("环信 - 删除好友响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 创建群组
     * @param string $group_name 群组名称
     * @param string $desc 描述
     * @param string $owner_username 管理者
     * @param array $members 群成员
     * @return array|string
     * @name:createGroup
     * @author: lisa
     * @datetime: 2023-05-17 17:43
     */
    public function createGroup($group_name, $desc, $owner_username, $members = [])
    {
        $data = [
            'groupname'    => str_replace(" ", "+", $group_name), // 群组名称，最大长度为 128 字符。如果有空格，则使用 “+” 代替。
            'description'  => str_replace(" ", "+", $desc), // 群群组描述，最大长度为 512 字符。如果有空格，则使用 “+” 代替。
            'public'       => true, // 是否是公开群。公开群可以被搜索到，用户可以申请加入公开群；私有群无法被搜索到，因此需要群主或群管理员添加，用户才可以加入。
            'maxusers'     => 100, // 群组最大成员数（包括群主），值为数值类型，默认值 200。不同套餐支持的人数上限不同，详见 产品价格。免费仅支持100
            'allowinvites' => true, // 是否允许群成员邀请用户加入群组
            'membersonly'  => false, // 邀请用户入群时是否需要被邀用户同意。
            'owner'        => $owner_username, // 群组的管理员。
            'members'      => $members, // 群组成员的用户 ID 数组。该数组可包含 1-100 个元素，不包含群主的用户 ID。
//            'custom' => '', // 群组扩展信息，例如可以给群组添加业务相关的标记，不要超过 1,024 字符。
        ];

        if (count($members) == 0) ExceptionSms::returnError("群成员不能为空");

        if (count($members) > 100) ExceptionSms::checkParams("每次添加群成员不可超过100个");

        if ((count($members) + 1) > $data['maxusers']) ExceptionSms::checkParams("群组成员总数不可超过{$data['maxusers']}个");

        $group = new Group($this->auth);

        $result = $group->createPublicGroup(
            $owner_username,
            $data['groupname'],
            $data['description'],
            $data['members'],
            $data['maxusers'],
            $data['membersonly']
        );
        \Log::info($result);
        \Log::info("环信 - 创建群组响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 修改群信息
     * @param $group_id
     * @param $group_name
     * @param $desc
     * @return array|bool
     * @name:updateGroup
     * @author: lisa
     * @datetime: 2023-05-17 17:50
     */
    public function updateGroup($group_id, $group_name, $desc)
    {
        $group  = new Group($this->auth);
        $result = $group->updateGroup([
            'group_id'    => $group_id,
            'groupname'   => $group_name,
            'public'      => true,
            'description' => $desc
        ]);

        \Log::info("环信 - 更新群组响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 删除群组
     * @param string $group_id 群主ID
     * @return array|bool
     * @name:deleteGroup
     * @author: lisa
     * @datetime: 2023-05-18 11:22
     */
    public function deleteGroup($group_id)
    {
        $group  = new Group($this->auth);
        $result = $group->destroyGroup($group_id);

        \Log::info("环信 - 删除群组响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 获取群组成员信息
     * @param string $type 类型：room聊天室 group群组
     * @param string $group_id 群组ID
     * @return array
     * @author: lisa
     * @datetime: 2023-05-18 12:32
     */
    public function getGroupMembers($type, $group_id)
    {
        $result = false;
        if ($this->isGroup($type)) {
            $group  = new Group($this->auth);
            $result = $group->listAllGroupMembers($group_id);
            \Log::info("环信 - 获取群组成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        } else if ($this->isRoom($type)) {
            $group  = new Room($this->auth);
            $result = $group->getRoom($group_id);
            \Log::info("环信 - 获取聊天室成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        }
        return $result;
    }

    /**
     * 添加群或聊天室成员
     * @param string $type 类型：room聊天室 group群组
     * @param string $group_id 群组或聊天室ID
     * @param array $members 成员集合
     * @return array|bool
     * @author: lisa
     * @datetime: 2023-05-18 10:17
     */
    public function addMembers($type, $group_id, $members = [])
    {
        if (count($members) == 0) $this->throwMsg('成员不能为空');
        if ($this->isGroup($type)) if (count($members) > 60) $this->throwMsg('每次最多可以添加60位成员');

        $result = false;
        if ($this->isGroup($type)) {
            $group  = new Group($this->auth);
            $result = $group->addGroupMembers($group_id, $members);
            \Log::info("环信 - 添加群组成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        } else if ($this->isRoom($type)) {
            $room = new Room($this->auth);
            $result = $room->addRoomMembers($group_id, $members);
            \Log::info("环信 - 添加聊天室成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        }
        return $result;
    }

    /**
     * 删除群或聊天室成员
     * @param string $type 类型：room聊天室 group群组
     * @param string $group_id
     * @param array $members 成员集合
     * @return array|bool
     * @author: lisa
     * @datetime: 2023-05-18 10:21
     */
    public function deleteMembers($type, $group_id, $members = [])
    {
        if (count($members) == 0) $this->throwMsg('成员不能为空');
        if ($this->isGroup($type)) if (count($members) > 60) $this->throwMsg('每次最多可以删除60位成员');
        $result = false;
        if ($this->isGroup($type)) {
            $group  = new Group($this->auth);
            $result = $group->removeGroupMembers($group_id, $members);
            \Log::info("环信 - 删除群组成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        } else if ($this->isRoom($type)) {
            $room = new Room($this->auth);
            $result = $room->removeRoomMembers($group_id, $members);
            \Log::info("环信 - 删除聊天室成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        }
        return $result;
    }

    /**
     * 添加群组管理员
     * @param string $type 类型：room聊天室 group群组
     * @param string $group_id
     * @param string $username
     * @return array|bool
     * @author: lisa
     * @datetime: 2023-05-18 10:23
     */
    public function addManager($type, $group_id, $username)
    {
        $result = false;
        if ($this->isGroup($type)) {
            $group  = new Group($this->auth);
            $result = $group->addGroupAdmin($group_id, $username);
            \Log::info("环信 - 添加群组管理员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        } else if ($this->isRoom($type)) {
            $room = new Room($this->auth);
            $result = $room->promoteRoomAdmin($group_id, $username);
            \Log::info("环信 - 添加聊天室管理员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        }
        return $result;
    }

    /**
     * 移除群组管理员
     * @param string $type 类型：room聊天室 group群组
     * @param string $group_id
     * @param string $username
     * @return array|bool
     * @author: lisa
     * @datetime: 2023-05-18 10:26
     */
    public function deleteManager($type, $group_id, $username)
    {
        $result = false;
        if ($this->isGroup($type)) {
            $group  = new Group($this->auth);
            $result = $group->removeGroupAdmin($group_id, $username);
            \Log::info("环信 - 移除群组管理员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        } else if ($this->isRoom($type)) {
            $room = new Room($this->auth);
            $result = $room->demoteRoomAdmin($group_id, $username);
        }
        return $result;
    }

    /**
     * 添加群组禁言成员
     * @param string $group_id
     * @param array $members
     * @return array|bool
     * @author: lisa
     * @datetime: 2023-05-18 10:32
     */
    public function addDisablers($group_id, $members = [])
    {
        if (count($members) == 0) $this->throwMsg('成员不能为空');
        if (count($members) > 60) $this->throwMsg('每次最多可以禁言10位成员');

        $block  = new Block($this->auth);
        $result = $block->blockUsersJoinGroup($group_id, $members);
        \Log::info("环信 - 添加群组禁言成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 移除群组禁言成员
     * @param $group_id
     * @param array $members
     * @return array|bool
     * @name:deleteDisablers
     * @author: lisa
     * @datetime: 2023-05-18 10:35
     */
    public function deleteDisablers($group_id, $members = [])
    {
        if (count($members) == 0) $this->throwMsg('成员不能为空');
        if (count($members) > 60) $this->throwMsg('每次最多可以解禁10位成员');
        $block  = new Block($this->auth);
        $result = $block->unblockUsersJoinGroup($group_id, $members);
        \Log::info("环信 - 移除群组禁言成员响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 创建聊天室
     * @param string $room_name 聊天室名称
     * @param string $desc 聊天室描述
     * @param string $owner_username 聊天室的管理员
     * @param array $members 成员
     * @return array|string
     * @name:createRoom
     * @author: lisa
     * @datetime: 2023-05-19 10:05
     */
    public function createRoom($room_name, $desc, $owner_username, $members = [])
    {
        $data = [
            'name'        => $room_name, // 聊天室名称，最大长度为 128 个字符。
            'description' => $desc, // 聊天室描述，最大长度为 512 个字符。
            'maxusers'    => 10000, // 聊天室最大成员数（包括聊天室所有者），默认最大值为 10,000，如需调整请联系商务。
            'owner'       => $owner_username, // 聊天室的管理员。
            'members'     => $members,
        ];
        if (count($members) == 0) $this->throwMsg('聊天室成员不能为空');
        $room = new Room($this->auth);
        $result = $room->createRoom($data['name'], $data['description'], $data['owner'], $data['members'], $data['maxusers']);
        \Log::info("环信 - 创建聊天室响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 更新聊天室信息
     * @param $room_id
     * @param $room_name
     * @param $desc
     * @return array|bool
     * @author: lisa
     * @datetime: 2023-05-19 10:19
     */
    public function updateRoom($room_id, $room_name, $desc)
    {
        $room = new Room($this->auth);
        $result = $room->updateRoom(['room_id' => $room_id, 'name' => $room_name, 'description' => $desc]);
        \Log::info("环信 - 更新聊天室响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    /**
     * 解散聊天室
     * @param $room_id
     * @return array|bool
     * @name:deleteRoom
     * @author: lisa
     * @datetime: 2023-05-19 10:19
     */
    public function deleteRoom($room_id)
    {
        $room = new Room($this->auth);
        $result = $room->destroyRoom($room_id);
        \Log::info("环信 - 解散聊天室响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    public function getGroups($type)
    {
        $result = false;
        if ($this->isRoom($type)) {
            $room = new Room($this->auth);
            $result = $room->listAllRooms();
        } else if ($this->isGroup($type)) {
            $group = new Group($this->auth);
            $result = $group->listAllGroups();
        }
        \Log::info("环信 - 获取群组和聊天室响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    public function getUserToken($username)
    {
        $result = $this->auth->getUserToken($username, $username, 86400);
        \Log::info("环信 - 获取用户信息响应信息：" . json_encode($result, JSON_UNESCAPED_UNICODE));
        return $result;
    }

    public function throwMsg($msg)
    {
        ExceptionSms::returnError("环信：" . $msg);
    }
}
